package haggisworld;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.text.DefaultCaret;

/**
 *
 * @author Büsra Göcen
 */
public class SpielerFenster extends JFrame {

    JPanel handKarten;
    ImageIcon[] kartenGruen;
    ImageIcon[] kartenGelb;
    ImageIcon[] kartenOrange;
    ImageIcon[] kartenRot;
    ImageIcon[] kartenAndere;
    JLabel[] kartenLabel;
    JLabel[] tischLabel;
    JTextField spielInfo1_wert;
    JTextField spielInfo2_wert;
    JTextField spielInfo3_wert;
    JTextField spielInfo4_wert;
    JTextField spielInfo5_wert;
    LinkedList<Karte> meineKarten = new LinkedList<Karte>();
    LinkedList<Karte> gelegteKarten = new LinkedList<Karte>();
    LinkedList<Karte> aufTisch = new LinkedList<Karte>();
    LinkedList<Karte> gegnerBonuskarten = new LinkedList<Karte>();
    final JTextArea text;
    int anzSpieler = 0;
    int spieler;
    int derAndereSpieler;
    int spielerAmZug;
    int runde;
    boolean gestartet = false;
    boolean beideVerbunden = false;
    JPanel tisch;
    GridLayout grid;
    SpielClient client;

    JMenu hilfeMenu;
    JMenu fileMenu;
    JMenuItem zeigeHilfeMenuItem;
    JMenuItem startItem;
    JMenuItem closeItem;
    JMenuBar mainMenuBar;

    /**
     * Diese Methode lädt die ImageIcons aller existierender Karten.
     */
    //ImageIcon Arrays werden instanziert; Array hat Länge [9] (1-9); Position zum Ansprechen für das Speichern ist 0-8 x[0],x[1] etc.
    public void ladeKartenbilder() {
        System.out.println("Methode ladeKartenbilder() gestartet");
        kartenGelb = new ImageIcon[9];
        kartenGruen = new ImageIcon[9];
        kartenOrange = new ImageIcon[9];
        kartenRot = new ImageIcon[9];
        kartenAndere = new ImageIcon[3];
        for (int i = 0; i < 9; i++) {
            kartenGruen[i] = new ImageIcon(getClass().getResource("../res/gruen/gruen0" + (i + 2) + ".jpg"));
            kartenGruen[i].setImage(kartenGruen[i].getImage().getScaledInstance(30, -1, Image.SCALE_SMOOTH));
            kartenGruen[i].setDescription("Gruen0" + (i + 2));//Label wird beschriftet für Referenz der Karte
        }
        for (int i = 0; i < 9; i++) {
            kartenGelb[i] = new ImageIcon(getClass().getResource("../res/gelb/gelb0" + (i + 2) + ".jpg"));
            kartenGelb[i].setImage(kartenGelb[i].getImage().getScaledInstance(30, -1, Image.SCALE_SMOOTH));
            kartenGelb[i].setDescription("Gelb0" + (i + 2));
        }
        for (int i = 0; i < 9; i++) {
            kartenOrange[i] = new ImageIcon(getClass().getResource("../res/orange/orange0" + (i + 2) + ".jpg"));
            kartenOrange[i].setImage(kartenOrange[i].getImage().getScaledInstance(30, -1, Image.SCALE_SMOOTH));
            kartenOrange[i].setDescription("Orange0" + (i + 2));
        }
        for (int i = 0; i < 9; i++) {
            kartenRot[i] = new ImageIcon(getClass().getResource("../res/rot/rot0" + (i + 2) + ".jpg"));
            kartenRot[i].setImage(kartenRot[i].getImage().getScaledInstance(30, -1, Image.SCALE_SMOOTH));
            kartenRot[i].setDescription("Rot0" + (i + 2));
        }
        for (int i = 0; i < 3; i++) {
            String[] andere = {"Bube", "Dame", "Koenig"};
            kartenAndere[i] = new ImageIcon(getClass().getResource("../res/andere/" + andere[i] + ".jpg"));
            kartenAndere[i].setImage(kartenAndere[i].getImage().getScaledInstance(30, -1, Image.SCALE_SMOOTH));
            kartenAndere[i].setDescription(andere[i]);
        }
    }

    /**
     * Diese Methode sortiert eine LinkedList mit Kartenobjekten.
     *
     * @param liste Die zu sortierende LinkedList.
     * @return Die sortierte LinkedList.
     */
    public LinkedList<Karte> sortiere(LinkedList<Karte> liste) {
        ListIterator iter = liste.listIterator();

        while (iter.hasNext()) {
            Collections.sort(liste, new VergleicheKartenWert());

            iter = liste.listIterator();

            while (iter.hasNext()) {
                System.out.println("Handkarten: " + iter.next());
            }
        }

        return liste;
    }

    /**
     * Diese Methode erhält die Karten, die sich aktuell auf dem Spieltisch
     * befinden. Der Spieltisch wird auf den aktuellen Bestand aktualisisert.
     *
     * @param objekt SpielObjekt mit dem aktuellen Tischbestand.
     */
    public void zeigeSpieltischAn(SpielObjekt objekt) {
        tisch.removeAll();
        tischLabel = new JLabel[16];
        if (objekt.getKarten(0) != null) {
            aufTisch = objekt.getKarten(0);//im objekt sind Kartenwerte die auf dem Tisch sind(erhalten vom Spielobjekt)Spielobjekt kommt vom Server

            ListIterator<Karte> listIterator = aufTisch.listIterator();//in dieser Liste sind die Karten auf dem Tisch

            int pos = 0;
            while (listIterator.hasNext()) {
                Karte kk = listIterator.next();//Liste auf Tisch
                String str = kk.getName();
                System.out.println("Spieltisch: " + kk.toString());

                //die ersten 2 Buchstaben von den Kartenliste auf Tisch nimmt es und überprüft ob es Bauer, Dame, König ist
                String farbe = str.substring(0, 2);

                if (farbe.equals("Bu") || farbe.equals("Da") || farbe.equals("Ko")) {
                    switch (farbe) {
                        case "Bu":
                            tischLabel[pos] = new JLabel(kartenAndere[0], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                        case "Da":
                            tischLabel[pos] = new JLabel(kartenAndere[1], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                        case "Ko":
                            tischLabel[pos] = new JLabel(kartenAndere[2], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                    }
                } else {
                    String format = str.substring((str.length() - 1), str.length());

                    int knr = Integer.parseInt(str.substring((str.length() - 1), str.length())) - 2;//weil karten bei 2 beginnen und array bei 0 beginnt
                    if (knr == -2) {//weil beim 010 nimmt es die letzte Nummer und subatrahiert 2 und damit ergibt sich -2, da es das nicht gibt setzt es auf 8, da 10 auf 8 parkiert ist im array
                        knr = 8;   // Falls knr Wert o hat (weil es von 10 abgeschnitten wurde, setze knr auf 10-2 -> 8
                    }

                    switch (farbe) {
                        case "Gr":
                            tischLabel[pos] = new JLabel(kartenGruen[knr], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                        case "Ge":
                            tischLabel[pos] = new JLabel(kartenGelb[knr], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                        case "Or":
                            tischLabel[pos] = new JLabel(kartenOrange[knr], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                        case "Ro":
                            tischLabel[pos] = new JLabel(kartenRot[knr], JLabel.CENTER);
                            tischLabel[pos].setName(pos + "");
                            break;
                    }
                }
                tisch.add(tischLabel[pos]);
                hinzufuegeActionListener(tischLabel[pos]);
                pos++;
            }
        }
        this.pack();//aktualisieren von frame
        this.setSize(780, 430);
        this.setVisible(true);
    }

    /**
     * Diese Methode zeigt die Karten des jeweiligen Spielers an.
     *
     * @param objekt SpielObjekt mit Kartenbestand
     */
    public void zeigeKartenAn(SpielObjekt objekt) {
        if (objekt.getVon() != null && objekt.getVon().equals("NEUES_SPIEL")) {
            starteNeuesSpiel(objekt);
            SpielObjekt leererTisch = new SpielObjekt();
            leererTisch.setKarten(null, 0);
            zeigeSpieltischAn(leererTisch);
        }
        gestartet = true;
        if (objekt.getRunde() > 0) { //Runde zählen
            runde = objekt.getRunde();
        }
        handKarten.removeAll();
        spielerAmZug = objekt.getAmZug();
        spielInfo2_wert.setText("" + runde);
        if (objekt.getKarten(0) != null && objekt.getKarten(0).size() == 17) {
            text.append("Runde " + runde + ": Es geht los!\n");
            gegnerBonuskarten.clear();
            Karte bube = new Karte("Bube", "Bonus", 11, 2);
            Karte dame = new Karte("Dame", "Bonus", 12, 3);
            Karte koenig = new Karte("Koenig", "Bonus", 13, 4);
            gegnerBonuskarten.add(bube);
            gegnerBonuskarten.add(dame);
            gegnerBonuskarten.add(koenig);
            spielInfo5_wert.setText("B D K");
        }
        if (spielerAmZug == spieler) {
            text.append("Spieler " + spieler + ": Sie sind am Zug!\n");
        }
        meineKarten = null;
        kartenLabel = new JLabel[17];//werden im LinkedList meineKarten gespeichert
        meineKarten = objekt.getKarten(spieler - 1);
        meineKarten = sortiere(meineKarten);//sortierMethode leitet an VergleicheKartenWert
        ListIterator<Karte> listIterator = meineKarten.listIterator();
        int pos = 0;
        while (listIterator.hasNext()) {
            Karte kk = listIterator.next();
            String str = kk.getName();

            String farbe = str.substring(0, 2);

            if (farbe.equals("Bu") || farbe.equals("Da") || farbe.equals("Ko")) {
                switch (farbe) {
                    case "Bu":
                        kartenLabel[pos] = new JLabel(kartenAndere[0], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                    case "Da":
                        kartenLabel[pos] = new JLabel(kartenAndere[1], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                    case "Ko":
                        kartenLabel[pos] = new JLabel(kartenAndere[2], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                }
            } else {

                int knr = Integer.parseInt(str.substring((str.length() - 1), str.length())) - 2;
                if (knr == -2) {
                    knr = 8;   // Falls knr Wert o hat (weil es von 10 abgeschnitten wurde, setze knr auf 10-2 -> 8
                }

                switch (farbe) {
                    case "Gr":
                        kartenLabel[pos] = new JLabel(kartenGruen[knr], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                    case "Ge":
                        kartenLabel[pos] = new JLabel(kartenGelb[knr], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                    case "Or":
                        kartenLabel[pos] = new JLabel(kartenOrange[knr], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                    case "Ro":
                        kartenLabel[pos] = new JLabel(kartenRot[knr], JLabel.CENTER);
                        kartenLabel[pos].setName(pos + "");
                        break;
                }
            }
            handKarten.add(kartenLabel[pos]);
            hinzufuegeActionListener(kartenLabel[pos]);
            pos++;
        }
        this.pack();
        this.setSize(780, 430);
        this.setVisible(true);
    }

    /**
     * Diese private Klasse vererbt ein JMenuItem.
     */
    private class MeinMenuItem extends JMenuItem implements ActionListener {

        Karte k1;
        String farbe;
        int nummer;
        int pos;
        Boolean markiert = false;

        /**
         * Konstruktor eines MeinMenuItem
         *
         * @param farbe die selektierte Farbe
         * @param nummer die selektierte Nummer
         * @param pos die Position innerhalb des Gridlayouts
         * @param k1 die gewählte Jokerkarte
         */
        public MeinMenuItem(String farbe, String nummer, int pos, Karte k1) {
            super(nummer);
            this.k1 = k1;
            this.farbe = farbe;
            this.nummer = Integer.parseInt(nummer);
            if (farbe.equals("Bube") || farbe.equals("Dame")) {
                super.setText(farbe);
            } else if (farbe.equals("Koenig")) {
                super.setText("König");
            }
            this.pos = pos;
            addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (!markiert) {
                System.out.println("setFarbe: " + this.farbe);
                k1.setFarbe(this.farbe);
                k1.setWert(this.nummer);
                gelegteKarten.add(k1);
                kartenLabel[pos].setBorder(new LineBorder(Color.BLACK, 2));
            }
        }

    }

    /**
     * Diese Methode fügt einen ActionListener zum JLabel hinzu.
     *
     * @param label Karte mit JLabel
     */
    public void hinzufuegeActionListener(final JLabel label) {

        label.addMouseListener(new MouseListener() {
            boolean markiert = false;

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 1) {
                    System.out.println("click");
                    int pos = Integer.parseInt(label.getName());
                    int count = 0;
                    if (!markiert) {

                        Karte k1 = meineKarten.get(pos);//Karte k1 ist zwischenspeicher
                        if (k1.getName().equals("Bube") || k1.getName().equals("Dame") || k1.getName().equals("Koenig")) {
                            JPopupMenu pop = new JPopupMenu();

                            JMenu menu = new JMenu();
                            JMenu menu1 = new JMenu("Grün");
                            JMenu menu2 = new JMenu("Rot");
                            JMenu menu3 = new JMenu("Orange");
                            JMenu menu4 = new JMenu("Gelb");
                            JMenu menu5 = new JMenu("Joker");

                            for (int i = 0; i < 4; i++) {
                                for (int j = 0; j < 9; j++) {
                                    switch (i) {
                                        case 0:
                                            if (j != 8) {
                                                JMenuItem item = new MeinMenuItem("Gruen", ("0" + (j + 2)), pos, k1);
                                                menu1.add(item);
                                            } else {
                                                JMenuItem item = new MeinMenuItem("Gruen", ("" + (j + 2)), pos, k1);
                                                menu1.add(item);
                                            }
                                            break;
                                        case 1:
                                            if (j != 8) {
                                                JMenuItem item = new MeinMenuItem("Rot", ("0" + (j + 2)), pos, k1);
                                                menu2.add(item);
                                            } else {
                                                JMenuItem item = new MeinMenuItem("Rot", ("" + (j + 2)), pos, k1);
                                                menu2.add(item);
                                            }
                                            break;
                                        case 2:
                                            if (j != 8) {
                                                JMenuItem item = new MeinMenuItem("Orange", ("0" + (j + 2)), pos, k1);
                                                menu3.add(item);
                                            } else {
                                                JMenuItem item = new MeinMenuItem("Orange", ("" + (j + 2)), pos, k1);
                                                menu3.add(item);
                                            }
                                            break;
                                        case 3:
                                            if (j != 8) {
                                                JMenuItem item = new MeinMenuItem("Gelb", ("0" + (j + 2)), pos, k1);
                                                menu4.add(item);
                                            } else {
                                                JMenuItem item = new MeinMenuItem("Gelb", ("" + (j + 2)), pos, k1);
                                                menu4.add(item);
                                            }
                                            break;
                                    }
                                }
                            }

                            JMenuItem menui9 = new MeinMenuItem("Bube", "11", pos, k1);
                            JMenuItem menui10 = new MeinMenuItem("Dame", "12", pos, k1);
                            JMenuItem menui11 = new MeinMenuItem("Koenig", "13", pos, k1);
                            menu5.add(menui9);
                            if (k1.getName().equals("Dame") || k1.getName().equals("Koenig")) {
                                menu5.add(menui10);
                            }
                            if (k1.getName().equals("Koenig")) {
                                menu5.add(menui11);
                            }
                            pop.add(menu1);
                            pop.add(menu2);
                            pop.add(menu3);
                            pop.add(menu4);
                            pop.add(menu5);
                            pop.show(e.getComponent(), e.getX(), e.getY());
                            markiert = true;
                        } // "Normale" Karte nach Doppelklick markieren und zu gelegteKarten hinzufügen.
                        else {
                            label.setBorder(new LineBorder(Color.BLACK, 2));
                            gelegteKarten.add(k1);
                            markiert = true;
                        }
                    } else {
                        Karte k1 = meineKarten.get(pos);
                        if (k1.getName().equals("Bube") || k1.getName().equals("Dame") || k1.getName().equals("Koenig")) {
                            label.setBorder(new LineBorder(Color.BLACK, 0));
                            for (int i = 0; i < gelegteKarten.size(); i++) {//es kann nicht mehr rückmarkieren als markiert sind
                                if (meineKarten.get(pos).getName().equals(gelegteKarten.get(i).getName())) {//überprüfung name
                                    gelegteKarten.remove(i);
                                    switch (meineKarten.get(pos).getName()) {
                                        case "Bube":
                                            meineKarten.get(pos).setWert(11);
                                            break;
                                        case "Dame":
                                            meineKarten.get(pos).setWert(12);
                                            break;
                                        case "Koenig":
                                            meineKarten.get(pos).setWert(13);
                                            break;
                                    }
                                    meineKarten.get(pos).setFarbe(meineKarten.get(pos).getName());
                                    System.out.println("Karte " + meineKarten.get(pos).getName() + " wieder entmarkiert.");
                                    System.out.println("Anzahl markierter Karten: " + gelegteKarten.size());
                                    break;
                                }
                            }
                            markiert = false;
                        } else {
                            label.setBorder(new LineBorder(Color.BLACK, 0));
                            for (int i = 0; i < gelegteKarten.size(); i++) {//es kann nicht mehr rückmarkieren als markiert sind
                                if (meineKarten.get(pos).getName().equals(gelegteKarten.get(i).getName())) {//überprüfung name
                                    gelegteKarten.remove(i);
                                    System.out.println("Karte " + meineKarten.get(pos).getName() + " wieder entmarkiert.");
                                    System.out.println("Anzahl markierter Karten: " + gelegteKarten.size());
                                    break;
                                }
                            }
                            markiert = false;
                        }
                    }
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
    }

    /**
     * Diese Methode überträgt die aktuellen Punkte des letzten Gewinners eines
     * Zuges, Stichs oder Spiels. Die jeweiligen Punkte werden dadurch im
     * spielInfo3_wert JLabel angezeigt.
     *
     * @author Büsra Göcen, Andreas Miksik
     *
     * @param objekt SpielObjekt mit dem aktuellen Punktestand eines Spielers.
     */
    public void zeigePunktestandAn(SpielObjekt objekt) {
        tisch.removeAll();
        zeigeSpieltischAn(objekt);
        spielerAmZug = objekt.getAmZug();
        if (("c" + spieler).equals(objekt.getAn())) {
            spielInfo3_wert.setText("" + objekt.getPunkte());
            text.append("Spieler " + spieler + ": Sie sind jetzt am Zug.\n");
        } else {
            if (objekt.getVon() != null && objekt.getVon().equals("NEUE_RUNDE")) {
                SpielObjekt bestaetigungsObjekt = new SpielObjekt("PUNKTE_ERHALTEN");
                client.sende(bestaetigungsObjekt);
            }
            spielInfo4_wert.setText("" + objekt.getPunkte());
        }
    }

    /**
     * Diese Methode setzt die Punkte und die Runde zurück
     *
     * @param resetObjekt Objekt mit Zahl des aktuellen Spiels
     */
    public void starteNeuesSpiel(SpielObjekt resetObjekt) {
        spielInfo1_wert.setText("" + resetObjekt.getSpiel());
        spielInfo2_wert.setText("1");
        spielInfo3_wert.setText("0");
        spielInfo4_wert.setText("0");
    }

    /**
     * Konstruktor der Klasse SpielerFenster
     *
     * @param spieler Die Nummer des Spielers
     * @param client Der zum Spielerfenster gehörende Spielclient
     * @throws IOException
     */
    public SpielerFenster(final int spieler, SpielClient client) throws IOException {
        this.setContentPane(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("wood.jpg")))));
        Image image = ImageIO.read(getClass().getResource("haggis_bild.jpg"));
        setIconImage(image);
        this.initMenu();
        this.client = client;
        setLayout(null);
        setSize(780, 430);
        if (spieler == 2) {
            derAndereSpieler = 1;
            setLocation(790, 200);
        } else {
            derAndereSpieler = 2;
            setLocation(0, 200);
        }
        setTitle("haggisWorld - Spieler " + spieler);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.spieler = spieler;

        handKarten = new JPanel();
        handKarten.setLocation(100, 285);
        handKarten.setSize(650, 70);
        handKarten.setBackground(Color.PINK);
        handKarten.revalidate();
        handKarten.setBorder(new LineBorder(Color.black, 2));
        handKarten.setLayout(grid = new GridLayout(1, 17));
        ladeKartenbilder();

        add(handKarten);

        JPanel spielInfoBox = new JPanel();
        spielInfoBox.setBorder(new LineBorder(Color.black, 1));
        spielInfoBox.setLayout(null);
        spielInfoBox.setLocation(600, 25);
        spielInfoBox.setBackground(Color.green);
        spielInfoBox.setSize(150, 110);
        add(spielInfoBox);

        JLabel spielInfo1 = new JLabel("Spiel:");
        Font fi1 = new Font("SansSerif", Font.BOLD, 11);
        spielInfo1.setFont(fi1);
        spielInfo1.setSize(60, 20);
        spielInfo1.setLocation(10, 5);
        spielInfoBox.add(spielInfo1);

        spielInfo1_wert = new JTextField("1");
        Font fi1_wert = new Font("SansSerif", Font.BOLD, 11);
        spielInfo1_wert.setFont(fi1_wert);
        spielInfo1_wert.setSize(20, 20);
        spielInfo1_wert.setLocation(120, 5);
        spielInfo1_wert.setEditable(false);
        spielInfoBox.add(spielInfo1_wert);

        JLabel spielInfo2 = new JLabel("Runde:");
        spielInfo2.setFont(fi1);
        spielInfo2.setSize(60, 20);
        spielInfo2.setLocation(10, 25);
        spielInfoBox.add(spielInfo2);

        spielInfo2_wert = new JTextField("1");
        spielInfo2_wert.setFont(fi1_wert);
        spielInfo2_wert.setSize(20, 20);
        spielInfo2_wert.setLocation(120, 25);
        spielInfo2_wert.setEditable(false);
        spielInfoBox.add(spielInfo2_wert);

        JLabel spielInfo3 = new JLabel("meine Punkte:");
        spielInfo3.setFont(fi1);
        spielInfo3.setSize(80, 20);
        spielInfo3.setLocation(10, 45);
        spielInfoBox.add(spielInfo3);

        spielInfo3_wert = new JTextField("0");
        spielInfo3_wert.setFont(fi1_wert);
        spielInfo3_wert.setSize(30, 20);
        spielInfo3_wert.setLocation(110, 45);
        spielInfo3_wert.setEditable(false);
        spielInfoBox.add(spielInfo3_wert);

        JLabel spielInfo4 = new JLabel("seine Punkte:");
        spielInfo4.setFont(fi1);
        spielInfo4.setSize(80, 20);
        spielInfo4.setLocation(10, 65);
        spielInfoBox.add(spielInfo4);

        spielInfo4_wert = new JTextField("0");
        spielInfo4_wert.setFont(fi1_wert);
        spielInfo4_wert.setSize(30, 20);
        spielInfo4_wert.setLocation(110, 65);
        spielInfo4_wert.setEditable(false);
        spielInfoBox.add(spielInfo4_wert);

        JLabel spielInfo5 = new JLabel("Joker:");
        spielInfo5.setFont(fi1);
        spielInfo5.setSize(80, 20);
        spielInfo5.setLocation(10, 85);
        spielInfoBox.add(spielInfo5);

        spielInfo5_wert = new JTextField("B D K");
        spielInfo5_wert.setFont(fi1_wert);
        spielInfo5_wert.setSize(40, 20);
        spielInfo5_wert.setLocation(100, 85);
        spielInfo5_wert.setEditable(false);
        spielInfoBox.add(spielInfo5_wert);

        text = new JTextArea(5, 10);
        JScrollPane srcPane = new JScrollPane(text,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        srcPane.setLocation(100, 25);
        srcPane.setSize(250, 90);
        srcPane.setBorder(new LineBorder(Color.black, 1));
        text.setBorder(BorderFactory.createCompoundBorder(text.getBorder(), BorderFactory.createEmptyBorder(2, 5, 2, 5)));
        text.setEditable(false);
        add(srcPane);
        DefaultCaret caret = (DefaultCaret) text.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

        JButton okBT = new JButton("OK");
        okBT.setBorder(new LineBorder(Color.black, 1));
        okBT.setBackground(Color.green);
        okBT.setBounds(10, 170, 75, 30);
        okBT.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (gelegteKarten.size() > 0) {
                    SpielObjekt sendeObjekt = new SpielObjekt("c" + spieler, "SPIELZUG");
                    sendeObjekt.setKarten(gelegteKarten, 0);
                    sendeSpielbefehl(sendeObjekt);
                } else {
                    text.append("Es wurden keine Karten ausgewählt.\n");
                }
            }
        });

        add(okBT);

        JButton passBT = new JButton("PASS");
        passBT.setBorder(new LineBorder(Color.black, 1));
        passBT.setBackground(Color.green);
        passBT.setBounds(10, 205, 75, 30);
        passBT.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                text.append("Spieler " + spieler + ": PASS \n");
                SpielObjekt sendeObjekt = new SpielObjekt("c" + spieler, "PASS");
                sendeSpielbefehl(sendeObjekt);
            }
        });

        add(passBT);

        tisch = new JPanel();
        tisch.setSize(430, 110);
        tisch.setBackground(Color.GRAY);
        tisch.setBorder(new LineBorder(Color.black, 2));
        tisch.setLayout(new FlowLayout(FlowLayout.CENTER, 8, 2));
        tisch.setLocation(100, 150);
        add(tisch);
        setVisible(true);
    }

    /**
     * Diese Methode aktualisiert den Jokerkartenbestand des Gegenspielers.
     *
     * @param objekt Objekt mit gespielten Jokerkarten des Gegners
     */
    private void aktualisiereGegnerbestand(SpielObjekt objekt) {
        System.out.println("Bonuskartenbestand: " + gegnerBonuskarten.size());
        if (!(objekt.getKarten(2) == null)) {
            ListIterator<Karte> iter = objekt.getKarten(2).listIterator();
            while (iter.hasNext()) {
                Karte tempKarte = iter.next();
                ListIterator<Karte> iter2 = gegnerBonuskarten.listIterator();
                while (iter2.hasNext()) {
                    Karte tempKarte2 = iter2.next();
                    if (tempKarte.getName().equals(tempKarte2.getName())) {
                        iter2.remove();
                        System.out.println("Bonuskartenbestand 2: " + gegnerBonuskarten.size());
                    }
                }
            }

        }
        if (gegnerBonuskarten.size() != 0) {
            ListIterator<Karte> iter3 = gegnerBonuskarten.listIterator();
            String text = "";
            while (iter3.hasNext()) {
                String sub = iter3.next().getName().substring(0, 1);
                text = text + sub + " ";
            }
            spielInfo5_wert.setText("");
            spielInfo5_wert.setText(text);
        } else {
            spielInfo5_wert.setText("");
        }
    }

    /**
     * Diese Methode aktualisiert den Kartenbestand nach einem gültigen Zug.
     */
    private void aktualisiereKartenbestand() {
        ListIterator<Karte> iter = gelegteKarten.listIterator();
        while (iter.hasNext()) {
            int indx = iter.nextIndex();
            Karte tempKarte = iter.next();
            String tempText = tempKarte.getName();
            ListIterator<Karte> iter2 = meineKarten.listIterator();
            while (iter2.hasNext()) {
                int index = iter2.nextIndex();
                Karte tempKarte2 = iter2.next();
                String tempText2 = tempKarte2.getName();
                if (tempText.equals(tempText2)) {
                    iter2.remove();
                    iter.remove();
                    System.out.println("Kartenbestand: " + meineKarten.size());
                }
            }
            if (meineKarten.size() == 0) {
                SpielObjekt sende = new SpielObjekt();
                sende.setNachricht("KEINE_KARTEN");
                sende.setVon("c" + spieler);
                client.sende(sende);
            }
        }

    }

    /**
     * Diese Methode erhält Spielinformationen und zeigt diese in der oberen
     * Infobox an..
     *
     * @param objekt SpielObjekt mit aktuellen Informationen.
     */
    public void erhalteSpielinfo(SpielObjekt objekt) {
        if (objekt.getNachricht().equals("WARTE")) {
            text.append("Warte auf weiteren Spieler... \n");
        } else if (objekt.getNachricht().equals("VERBUNDEN")) {
            beideVerbunden = true;
            text.append("Zwei Spieler sind verbunden. \nSpiel über Menüleiste starten. \n");
        } else if (objekt.getNachricht().equals("VERBINDUNG_UNTERBROCHEN")) {
            text.append("==Verbindung unterbrochen==\n==Bitte Spiel neu starten==\n");
        } else if (objekt.getNachricht().equals("SPIELZUG_UNGUELTIG") && objekt.getAn().equals("c" + spieler)) {
            text.append("Spielzug ungültig.\nBitte andere Kombination spielen.\n");
        } else if (objekt.getNachricht().equals("SPIELZUG_UNGUELTIG") && objekt.getAn().equals("c" + derAndereSpieler)) {
        } else {
            text.append(objekt.getNachricht() + "\n");
        }
    }

    /**
     * Diese Methode sendet die übrigen Handkarten an den Server zur Auswertung
     * der Punkte. Der Server verlangt die Handkarten, nachdem ein User keine
     * Karten mehr hat.
     *
     * @param objekt SpielObjekt mit Handkarten des Spielers
     */
    public void sendeHandkarten(SpielObjekt objekt) {
        if (objekt.getAn().equals("c" + spieler)) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(Spiel.class.getName()).log(Level.SEVERE, null, ex);
            }
            SpielObjekt handkartenObjekt = new SpielObjekt("SENDE_HANDKARTEN");
            handkartenObjekt.setKarten(meineKarten, 0);
            handkartenObjekt.setVon("c" + spieler);
            client.sende(handkartenObjekt);
        }
    }

    /**
     * Diese Methode erhält aktuelle Informationen zum Spielablauf.
     *
     * @param objekt SpielObjekt mit Informationen zu den Spielzügen
     */
    public void erhalteSpielstatus(SpielObjekt objekt) {
        System.out.println("GetAn: " + objekt.getAn());
        spielerAmZug = objekt.getAmZug();
        tisch.removeAll();

        if (objekt.getAn().equals("c" + spieler)) {

            SpielObjekt info = new SpielObjekt();
            info.setNachricht("Spieler " + spieler + ": Spielzug korrekt.\nSpieler " + derAndereSpieler + " ist am Zug.\n");
            aktualisiereKartenbestand();
            SpielObjekt aktuell = new SpielObjekt();
            aktuell.setKarten(meineKarten, spieler - 1);
            erhalteSpielinfo(info);
            handKarten.removeAll();
            zeigeKartenAn(aktuell);
            zeigeSpieltischAn(objekt);//bei beiden Tischen sieht man dieselben Karten
        } else {
            aktualisiereGegnerbestand(objekt);
            SpielObjekt aktuell = new SpielObjekt();
            SpielObjekt info = new SpielObjekt();
            info.setNachricht("Gültiger Spielzug von anderem Spieler. \n" + "Spieler " + spieler + ": Sie sind jetzt am Zug.\n");
            erhalteSpielinfo(info);
            zeigeSpieltischAn(objekt);//bei beiden Tischen sieht man dieselben Karten
        }
    }

    /**
     * Diese Methode ruft die methode sende() vom Client auf.
     *
     * @param sendeObjekt Das zu sendende Objekt mit Spielinformationen
     */
    public void sendeSpielbefehl(SpielObjekt sendeObjekt) {
        if (spieler == spielerAmZug) {
            sendeObjekt.setVon("c" + spieler);
            sendeObjekt.setAmZug(spieler);
            client.sende(sendeObjekt);
        } else if (!gestartet) {
            text.append("Bitte Spiel zuerst starten.\n");
        } else {
            text.append("Spieler " + derAndereSpieler + " ist am Zug.\n");
        }
    }

    /**
     * Diese Methode initialisiert das SpielMenu.
     *
     */
    private void initMenu() {
        this.mainMenuBar = new JMenuBar();
        this.fileMenu = new JMenu("Spiel");
        this.startItem = new JMenuItem("Spiel starten");
        this.startItem.addActionListener(new ActionListener() {
            @Override
            /**
             * Diese Methode führt Aktionen durch.
             */
            public void actionPerformed(ActionEvent e) {
                if ((!gestartet) && beideVerbunden) {
                    SpielObjekt sendeObjekt = new SpielObjekt("c" + spieler, "STARTOBJEKT");
                    client.sende(sendeObjekt);
                } else if (gestartet) {
                    text.append("Spiel läuft bereits.\n");
                } else if (!beideVerbunden) {
                    text.append("Warten Sie auf weiteren Spieler.\n");
                }
            }
        });
        this.closeItem = new JMenuItem("Spiel beenden");
        Action exitAction = new AbstractAction("Beenden") {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        };
        this.closeItem.addActionListener(exitAction);

        this.mainMenuBar.add(this.fileMenu);
        this.fileMenu.add(this.startItem);
        this.fileMenu.add(this.closeItem);

        this.hilfeMenu = new JMenu("Hilfe");
        this.zeigeHilfeMenuItem = new JMenuItem("Spielanleitung");
        this.zeigeHilfeMenuItem.addActionListener(new ZeigeHilfeListener());

        this.hilfeMenu.add(this.zeigeHilfeMenuItem);
        this.mainMenuBar.add(this.hilfeMenu);

        this.setJMenuBar(this.mainMenuBar);
    }
}
